package utilidades;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import Inscripcion.Participante;
import Inscripcion.Usuario;


@WebListener
public class MyServletListenerRegistro implements ServletContextListener{
	/* (non-Javadoc)
	 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
	 */
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		// Obtener el HashTable de participantes del servletContext
		HashMap<String, Usuario> registrados = 
				(HashMap<String, Usuario>) event.getServletContext().getAttribute("registrados");
		
		// Obtener la ruta del fichero de persistencia de participantes
		String rutaRelativa = "/WEB-INF/Persistencia/registrados.xml";
		String rutaDisco = event.getServletContext().getRealPath(rutaRelativa);
		
		// Invocar al método de parseado de la estructura de datos que construye el XML
		Escritor.guardarRegistrados(rutaDisco,registrados);
	}

//	private void guardarRegistrados(String rutaDisco,
//			HashMap<String, Usuario> registrados) {
//		
//		DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
//		try {
//			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
//			
//			// Creo el elemento raiz de la estructura
//			Document doc = docBuilder.newDocument();
//			Element raiz = doc.createElement("ListaRegistrados");
//			// Añado el elemento al documento
//			doc.appendChild(raiz);
//			
//			// Obtengo todos los participantes de la tabla
//			ArrayList<Usuario> listaRegistrados = getListaRegistrados(registrados);
//			
//			// Itero sobre ellos y los voy añadiendo a la raiz
//			for(int i = 0; i < listaRegistrados.size();i++){
//				Element nodo = getElementoRegistrado(listaRegistrados.get(i),doc);
//				raiz.appendChild(nodo);
//			}
//			// Genero el fichero de salida
//			
//			//TODO Pasar la salida a metodo independiente para reciclar el c�digo
//			TransformerFactory transformerFactory = TransformerFactory.newInstance();
//			Transformer transformer;
//			try {
//				transformer = transformerFactory.newTransformer();
//			
//				DOMSource source = new DOMSource(doc);
//				StreamResult result = new StreamResult(new File(rutaDisco));
//	 
//				// Output to console for testing
//				//result = new StreamResult(System.out);
//	 
//			transformer.transform(source, result);
//			
//			} catch (TransformerConfigurationException ce) {
//				// TODO Auto-generated catch block
//				ce.printStackTrace();
//			} catch (TransformerException te) {
//				// TODO Auto-generated catch block
//				te.printStackTrace();
//			}
//			System.out.println("Fichero salvado");
//			
//		} catch (ParserConfigurationException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}

//	private Element getElementoRegistrado(Usuario registrado, Document doc) {
//		
//		//Creamos la raiz del usuario
//		Element dev = doc.createElement("Usuario");
//		Attr attr = doc.createAttribute("id");
//		
//		
//	    
//		attr.setValue(registrado.getId());
//		dev.setAttributeNode(attr);
//		
//		//Introducimos los distintos elementos hijos de usuario
//		Element nombre = doc.createElement("Nombre");
//		nombre.appendChild(doc.createTextNode(registrado.getNombre()));
//		dev.appendChild(nombre);
//		
//		Element apellido1 = doc.createElement("Apellido1");
//		apellido1.appendChild(doc.createTextNode(registrado.getApellido1()));
//		dev.appendChild(apellido1);
//		
//		Element apellido2 = doc.createElement("Apellido2");
//		apellido2.appendChild(doc.createTextNode(registrado.getApellido2()));
//		dev.appendChild(apellido2);
//		
//		Element correo = doc.createElement("Correo");
//		correo.appendChild(doc.createTextNode(registrado.getCorreo()));
//		dev.appendChild(correo);
//		
//		Element username = doc.createElement("Username");
//		username.appendChild(doc.createTextNode(registrado.getUsername()));
//		dev.appendChild(username);
//		
//		Element password = doc.createElement("Password");
//		password.appendChild(doc.createTextNode(registrado.getPassword()));
//		dev.appendChild(password);		
//		
//		
//		Element sexo = doc.createElement("Sexo");
//		sexo.appendChild(doc.createTextNode(registrado.getSexo()));
//		dev.appendChild(sexo);
//		
//		return dev;
//	}

//	private ArrayList<Usuario> getListaRegistrados(
//			HashMap<String, Usuario> registrados) {
//
//		ArrayList<Usuario> dev = new ArrayList<Usuario>();
//		Iterator<String> it = registrados.keySet().iterator();
//		
//		while(it.hasNext()){
//			Usuario aux = registrados.get(it.next());
//			if(aux != null)
//				dev.add(aux);
//		}
//		
//		return dev;
//	}

	/* (non-Javadoc)
	 * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
	 */
	@Override
	public void contextInitialized(ServletContextEvent event) {

		String rutaRelativa = "/WEB-INF/Persistencia/registrados.xml";
		String rutaDisco = event.getServletContext().getRealPath(rutaRelativa);
		System.out.println(rutaDisco);
		HashMap<String, Usuario> registrados = cargarRegistrados(rutaDisco);
		event.getServletContext().setAttribute("registrados", registrados);		
	}

	
	
	private HashMap<String, Usuario> cargarRegistrados(String rutaDatosUsuarios) {

		HashMap<String, Usuario> dev = new HashMap<String, Usuario>();
		
		try {
			  DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			  DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			  System.out.println(rutaDatosUsuarios);
			  Document doc = dBuilder.parse(new File(rutaDatosUsuarios));
			  doc.getDocumentElement().normalize();

			  System.out.println("El elemento raíz es: " + doc.getDocumentElement().getNodeName());
			  NodeList listaPersonas = doc.getElementsByTagName("Usuario");

			  for (int i = 0; i < listaPersonas.getLength(); i ++) {

			    Node persona = listaPersonas.item(i);

			    if (persona.getNodeType() == Node.ELEMENT_NODE) {

		            Element elemento = (Element) persona;

		            System.out.println("Nombre : " + getTagValue("Nombre", elemento));
		            System.out.println("Apellido1 : " + getTagValue("Apellido1", elemento));
		            System.out.println("Apellido2 : " + getTagValue("Apellido2", elemento));
		            System.out.println("Correo : " + getTagValue("Correo", elemento));
		            System.out.println("Username : " + getTagValue("Username", elemento));
		            System.out.println("Password : " + getTagValue("Password", elemento));
		            System.out.println("Sexo : " + getTagValue("Sexo", elemento));
		            Usuario p = getUsuario(elemento);
		            
		            
		          //Insertamos el usuario en nuestra tabla
					String clave = p.getUsername();
					dev.put(clave, p);   
			    }
		    }
		  } catch (Exception e) {
		    e.printStackTrace();
		  }
		  
		return dev;
	}

	/**
	 * Extrae la información de participante contenida en el elm pasado como parámetro
	 * 
	 * @param elm
	 * @return
	 */
	private Usuario getUsuario(Element elm) {
		
		String uid = elm.getAttribute("uid");
		String nombre = getTagValue("Nombre",elm);
		String apellido1 = getTagValue("Apellido1",elm);
		String apellido2 = getTagValue("Apellido2",elm);
		String correo = getTagValue("Correo",elm); 
		String username = getTagValue("Username",elm);
		String password = getTagValue("Password",elm);		
		String sexo = getTagValue("Sexo",elm);
		
		UUID id2 = UUID.randomUUID();
		
		
		return new Usuario(nombre, apellido1, apellido2, correo, username, password, sexo, id2.toString());
	}
	
	/**
	 * Devuelve el valor del hijo con etiqueta sTag del elemento de jDom elm
	 * 
	 * @param sTag
	 * @param elm
	 * @return String con el valor del nodo
	 */
	private static String getTagValue(String sTag, Element elm) {
		NodeList nlList = elm.getElementsByTagName(sTag).item(0).getChildNodes();
	 
		Node nValue = (Node) nlList.item(0);
	 
		return nValue.getNodeValue();
	}
}
